package hooks

import (
	"io"
	"strings"
	"testing"

	"github.com/stretchr/testify/assert"
)

func Test_blockEOFBuffer_BigBufferBigRead(t *testing.T) {
	rd := strings.NewReader("0123456789")
	goon := make(chan struct{})
	beb := NewBlockEOFBuffer(goon, rd, 0)

	data := make([]byte, 100)

	n, err := beb.Read(data)
	assert.NoError(t, err)
	assert.Equal(t, 9, n)
	assert.Equal(t, "012345678", string(data[:n]))

	close(goon)
	n, err = beb.Read(data)
	assert.Equal(t, io.EOF, err)
	assert.Equal(t, 1, n)
	assert.Equal(t, "9", string(data[:n]))
}

func Test_blockEOFBuffer_SmallBufferBigRead(t *testing.T) {
	rd := strings.NewReader("0123456789")
	goon := make(chan struct{})
	beb := NewBlockEOFBuffer(goon, rd, 4)

	data := make([]byte, 100)

	n, err := beb.Read(data)
	assert.NoError(t, err)
	assert.Equal(t, 3, n)
	assert.Equal(t, "012", string(data[:n]))

	n, err = beb.Read(data)
	assert.NoError(t, err)
	assert.Equal(t, 4, n)
	assert.Equal(t, "3456", string(data[:n]))

	n, err = beb.Read(data)
	assert.NoError(t, err)
	assert.Equal(t, 2, n)
	assert.Equal(t, "78", string(data[:n]))

	close(goon)
	n, err = beb.Read(data)
	assert.Equal(t, io.EOF, err)
	assert.Equal(t, 1, n)
	assert.Equal(t, "9", string(data[:n]))
}

func Test_blockEOFBuffer_BigBufferSmallRead(t *testing.T) {
	rd := strings.NewReader("0123456789")
	goon := make(chan struct{})
	beb := NewBlockEOFBuffer(goon, rd, 100)

	data := make([]byte, 4)

	n, err := beb.Read(data)
	assert.NoError(t, err)
	assert.Equal(t, 3, n)
	assert.Equal(t, "012", string(data[:n]))

	n, err = beb.Read(data)
	assert.NoError(t, err)
	assert.Equal(t, 4, n)
	assert.Equal(t, "3456", string(data[:n]))

	n, err = beb.Read(data)
	assert.NoError(t, err)
	assert.Equal(t, 2, n)
	assert.Equal(t, "78", string(data[:n]))

	close(goon)
	n, err = beb.Read(data)
	assert.Equal(t, io.EOF, err)
	assert.Equal(t, 1, n)
	assert.Equal(t, "9", string(data[:n]))
}

func Test_blockEOFBuffer_SmallBufferSmallRead(t *testing.T) {
	rd := strings.NewReader("01234567")
	goon := make(chan struct{})
	beb := NewBlockEOFBuffer(goon, rd, 4)

	data := make([]byte, 4)

	n, err := beb.Read(data)
	assert.NoError(t, err)
	assert.Equal(t, 3, n)
	assert.Equal(t, "012", string(data[:n]))

	n, err = beb.Read(data)
	assert.NoError(t, err)
	assert.Equal(t, 4, n)
	assert.Equal(t, "3456", string(data[:n]))

	close(goon)
	n, err = beb.Read(data)
	assert.Equal(t, io.EOF, err)
	assert.Equal(t, 1, n)
	assert.Equal(t, "7", string(data[:n]))
}

func Test_blockEOFBuffer_EmptyReader(t *testing.T) {
	rd := strings.NewReader("")
	goon := make(chan struct{})
	beb := NewBlockEOFBuffer(goon, rd, 0)

	data := make([]byte, 4)

	close(goon)
	n, err := beb.Read(data)
	assert.Equal(t, io.EOF, err)
	assert.Equal(t, 0, n)
	assert.Equal(t, "", string(data[:n]))
}
